package com.alibaba.csp.sentinel.dashboard.config;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.appollo.ApolloConfig;
import com.alibaba.csp.sentinel.dashboard.rule.appollo.FlowRuleApolloProvider;
import com.alibaba.csp.sentinel.dashboard.rule.appollo.FlowRuleApolloPublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.FlowRuleNacosProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.FlowRuleNacosPublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Properties;

/**
 * @author: shaozeming
 * @date: 2022/8/12 17:03
 * @description:
 **/
@Configuration
public class DataBaseAutoConfiguration {


    @ConditionalOnProperty(name = "dashboard.nacos.enable",havingValue = "true")
    @Bean
    public ConfigService nacosConfigService(NacosConfig nacosConfig) throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, nacosConfig.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE, nacosConfig.getNamespace());
        return NacosFactory.createConfigService(properties);
    }

    @ConditionalOnBean(ConfigService.class)
    @Bean
    public DynamicRuleProvider<List<RuleEntity>> dynamicRuleNacosProvider(ConfigService configService,NacosConfig nacosConfig){
        return new FlowRuleNacosProvider(configService,nacosConfig);
    }


    @ConditionalOnBean(ConfigService.class)
    @Bean
    public DynamicRulePublisher<List<RuleEntity>> dynamicRuleNacosPublisher(ConfigService configService,NacosConfig nacosConfig){
        return new FlowRuleNacosPublisher(configService,nacosConfig);
    }


    @ConditionalOnProperty(name = "dashboard.apollo.enable",havingValue = "true")
    @Bean
    public ApolloOpenApiClient apolloOpenApiClient(ApolloConfig apolloConfig) throws NacosException {
        return ApolloOpenApiClient.newBuilder()
                .withPortalUrl(apolloConfig.getPortalUrl())
                .withToken(apolloConfig.getToken())
                .build();
    }

    @ConditionalOnBean(ApolloOpenApiClient.class)
    @Bean
    public DynamicRuleProvider<List<RuleEntity>> dynamicRuleApolloProvider(ApolloOpenApiClient apolloOpenApiClient,ApolloConfig apolloConfig){
        return new FlowRuleApolloProvider(apolloOpenApiClient,apolloConfig);
    }


    @ConditionalOnBean(ApolloOpenApiClient.class)
    @Bean
    public DynamicRulePublisher<List<RuleEntity>> dynamicRuleApolloPublisher(ApolloOpenApiClient apolloOpenApiClient,ApolloConfig apolloConfig){
        return new FlowRuleApolloPublisher(apolloOpenApiClient,apolloConfig);
    }
}
